package benchmark;

import java.util.*;

public class Benchmarker {
	
	final static int REPEAT_TIME = 1;
	
	final static boolean DETAILED_RESULTS = false;
	
	public static String run(List<String> args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		String taskName = args.get(0);
		Class<?> c = Class.forName("benchmark." + taskName);
		
		ITask task = (ITask)c.newInstance();
		task.init(args);
		
//		preheat(task);
		
		String record = "";
		for (int i = 1; i < args.size(); i++) {
			record += args.get(i) + "\t";
		}

		if (DETAILED_RESULTS) {
			List<Long> results = runDetailed(task, REPEAT_TIME);
			record += "\n";
			for (long r : results) {
				record += Long.toString(r) + "\n";
			}
			
		} else {
			long result = run(task, REPEAT_TIME);
			record += Long.toString(result) + "\n";
		}
		
		
		return record;
	}
	
	public static long run(ITask task, int repeatTime) {
		String output = "";
		long startTime = System.nanoTime();
		while ((repeatTime--) > 0) {
			output += task.runTask();
		}
		long duration = System.nanoTime() - startTime;
		
		System.out.println(output);
		return duration;
	}

	public static List<Long> runDetailed(ITask task, int repeatTime) {
		String output = "";
		List<Long> results = new ArrayList<Long>();
		while ((repeatTime--) > 0) {
			long startTime = System.nanoTime();
			output += task.runTask();
			long duration = System.nanoTime() - startTime;
			results.add(duration);
		}
		
		System.out.println(output);
		return results;
	}
	
	public static void preheat(ITask task) {
		String output = "";
		
		long startTime = System.nanoTime();
		long duration = 0;
		while (duration < 1000 * 1000 * 1000) {
			output += task.runTask();
			duration = System.nanoTime() - startTime;
		}
		
		System.out.println("preheat:" + output);
		
	}
	
	/**
	 * @param args
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws ClassNotFoundException 
	 */
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		
//		int len = 1000;
//		String []param = {Integer.toString(len)};
//
//		ArrayRead t = new ArrayRead();
//		
//		t.init(Arrays.asList(param));
//
//		String log = "";
//		for(int rt = 1; rt <= 10000; rt += 10) {
//			long duration = run(t, rt);
//			long average = duration / rt;
//			log += String.format("%d\t%d\n", rt, average);
//		}
//		
//		Output.toFile(log, new File("repeat.data"));
		
		
//		String[] param = {"FSArray", "1", "1"};
		
	
		
//		for(int i = 1; i <= 12; i++) {
//			String[] param = {"FSObject", "2", Integer.toString(i)};
//			
//			System.out.println(run(Arrays.asList(param)));
//			
//		}
				
//		System.out.println(run(Arrays.asList(param)));
//		System.out.println(run(Arrays.asList(param)));
//		System.out.println(run(Arrays.asList(param)));
//		System.out.println(run(Arrays.asList(param)));
//		System.out.println(run(Arrays.asList(param)));
//		System.out.println(run(Arrays.asList(param)));
//		System.out.println(run(Arrays.asList(param)));
//		System.out.println(run(Arrays.asList(param)));
//		System.out.println(run(Arrays.asList(param)));
		
//		try {
//			Thread.sleep(10000);
//		} catch (InterruptedException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		
//		String[] param = {"ArrayRead", 
//				Integer.toString(32 * 1024), 
//				Integer.toString(256 * 1024), 
//				Integer.toString(6144 * 1024), 
//				Integer.toString(6 * 1024 * 1024),
//				"0"};
		
//		String[] param = {"RepeatLinearRead", "1", "2048"};
		
//		String[] param = {"ArrayRead", 
//				Integer.toString(32 * 1024), 
//				Integer.toString(256 * 1024), 
//				Integer.toString(6144 * 1024), 
//				Integer.toString(32 * 1024), 
//				"0"};

//		String[] param = {"RepeatRun", 
//				Integer.toString(1000), 
//				Integer.toString(1 * 1024)};
//
//		int repeatTime = 10;
//		while (repeatTime-- > 0) {
//			System.out.println(run(Arrays.asList(param)));
//		}

		System.out.println(run(testParam()));

	}
	
	private static List<String> testParam() {
		String[] param = {"FSByteBuffer", 
				Integer.toString(2), 
				Integer.toString(1)};
		return Arrays.asList(param);
	}

}
